#pragma once

#include <iostream>
#include <strings.h>
#include <cstring>
#include <unistd.h>
#include <wait.h>
#include <pthread.h>
#include <functional>

#include "Socket.hpp"

using server_task_t = std::function<void(mySocket::Socket*, InetAddr)>;

class tcpServer
{
private:
    struct threadData
    {
        threadData(mySocket::socket_ptr sockfd, InetAddr addr, tcpServer *self)
            : _sockfd(sockfd), _addr(addr), _self(self)
        {}

        mySocket::socket_ptr _sockfd;
        InetAddr _addr;
        tcpServer *_self;
    };

public:
    tcpServer(uint16_t port, server_task_t task)
        : _listen_sockfd(new mySocket::tcpSocket),
          _server_addr(port, "0"),
          _task(task)
    {
        _listen_sockfd->tcpServerInit(_server_addr);
    }

    static void *serverHandler(void *arg)
    {
        pthread_detach(pthread_self());
        threadData *data = (threadData *)arg;
        
        data->_self->_task(data->_sockfd, data->_addr);

        delete data;
        close(data->_sockfd->getSockd());
        return nullptr;
    }


    void serverLoop()
    {
        LOG(DEBUG, "serverLoop begin.....");

        while (true)
        {
            // 记录请求连接方（client）的socket信息
            InetAddr clientAddr;

            // 接收连接
            mySocket::socket_ptr sockfd = _listen_sockfd->socketAccept(&clientAddr);
            if (sockfd == nullptr)
                continue;

            // v2多线程
            pthread_t tid;
            threadData *data = new threadData(sockfd, clientAddr, this);
            int ret = pthread_create(&tid, nullptr, serverHandler, data);
        }
    }

    const mySocket::socket_ptr geteListenSockfd()
    {
        return _listen_sockfd;
    }

private:
    InetAddr _server_addr;
    mySocket::socket_ptr _listen_sockfd;
    server_task_t _task;
};